package org.knot.mockejb3.interceptor;

import java.util.*;

/**
 * Stores the information about all calls to the target object 
 * in the list. Clients can examine the list to see the parameters of the calls. 
 * Example of usage:
 * <code><pre>
 *  InvocationRecorder recorder = new InvocationRecorder();
 *  aspectSystem.add( new ClassPointcut( SampleHelper.class, false), recorder);        
 *  InvocationContext dummyMethodInvocation = recorder.findByTargetMethod( "dummyMethod");
 *  assertNotNull(dummyMethodInvocation);
 * </pre></code>
 * 
 */
public class InvocationRecorder implements Interceptor {
    
    private List invocationContextList = new ArrayList();
    
    public void intercept( InvocationContext invocationContext ) throws Exception {
        
        Exception thrownException = null;
        Object returnObj = null;        

        try {
            invocationContext.proceed();
        }
        finally {
            
            invocationContextList.add( invocationContext );
        }
    
    }
    
    /**
     * Returns the list of all invocations that happened since the recorder 
     * was added.
     * @return list of invocations
     */
    public List getMethodInvocationList(){
        return invocationContextList;
    }
    
    /**
     * Returns true is it has at least one record
     * 
     * @return true if at least one recording was made
     */
    public boolean hasRecords(){
        return ! invocationContextList.isEmpty();
    }

    /**
     * Clears all currently stored invocations
     */
    public void clear() {
        invocationContextList.clear();
    }

    /**
     * Finds the first invocation for a given target method pattern.
     * @param methodPattern regexp pattern to run against the string representation of a method  
     * @return invocation context or null if method not found 
     * 
     */
    public InvocationContext findByTargetMethod( String methodPattern ){
        
        RegexpWrapper regexp = new RegexpWrapper( methodPattern );
        
        Iterator i = invocationContextList.iterator();

        while( i.hasNext() ){
            InvocationContext invocation = (InvocationContext) i.next();
            if ( regexp.containedInString( invocation.getTargetMethod().toString()  ) )
                return invocation;                    
        }
        
        return null;
    }
    
    /**
     * @deprecated Use findByProxyMethod instead
     * @param methodPattern regexp pattern to run against the string representation of a method
     * @return invocation context or null if method not found
     */
    public InvocationContext findByInterceptedMethod( String methodPattern ){ 
        return findByProxyMethod( methodPattern );
    }
    
    
    /**
     * Finds the first invocation for a given proxy method pattern.
     * @param methodPattern regexp pattern to run against the string representation of a method  
     * @return invocation context or null if method not found 
     * 
     */
    public InvocationContext findByProxyMethod( String methodPattern ){
        
        RegexpWrapper regexp = new RegexpWrapper( methodPattern );
        Iterator i = invocationContextList.iterator();

        while( i.hasNext() ){
            InvocationContext invocation = (InvocationContext) i.next();
            if ( regexp.containedInString( invocation.getProxyMethod().toString()  ) )
                return invocation;                    
        }
        
        return null;
    }
    
    public String toString( ){
        return invocationContextList.toString();
    }
    
}
